package com.party.web.biz.order;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.LangUtils;
import com.party.common.utils.PartyCode;
import com.party.common.utils.UUIDUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.Activity;
import com.party.core.model.activity.ApplyInput;
import com.party.core.model.charge.PackageMember;
import com.party.core.model.charge.ProductPackage;
import com.party.core.model.member.*;
import com.party.core.model.order.*;
import com.party.core.model.order.Output.OrderOutput;
import com.party.core.model.order.input.BookOrderInput;
import com.party.core.model.partner.MemberPartner;
import com.party.core.model.system.SysConfig;
import com.party.core.model.system.SysRole;
import com.party.core.model.system.TargetType;
import com.party.core.model.wallet.Withdrawals;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.activity.OrderActivityBizService;
import com.party.core.service.charge.IPackageService;
import com.party.core.service.member.*;
import com.party.core.service.member.util.MemberFormUtil;
import com.party.core.service.order.IOrderFormService;
import com.party.core.service.order.IOrderFormSubInfoService;
import com.party.core.service.partner.IMemberPartnerService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.wallet.biz.WithdrawalsBizService;
import com.party.web.biz.charge.PackageBizService;
import com.party.web.utils.RealmUtils;
import com.party.web.web.dto.input.common.CommonInput;
import com.party.web.web.dto.output.order.OrderFormOutput;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.*;

@SuppressWarnings("all")
@Service
public class OrderBizService {

	@Autowired
	private IOrderFormService orderFormService;
	@Autowired
	private IMemberService memberService;
	@Autowired
	private WithdrawalsBizService withdrawalsBizService;
	@Autowired
	private OrderActivityBizService orderActivityBizService;
	@Autowired
	private PackageBizService packageBizService;
	@Autowired
	private IPackageService packageService;
	@Autowired
	ISysConfigService sysConfigService;
	@Autowired
	private IPackageCountService packageCountService;
	@Autowired
	private IMemberGroupInfoService memberGroupInfoService;
	@Autowired
	private IMemberMerchantService memberMerchantService;
	@Autowired
	private IMemberPartnerService memerPartnerService;
	@Autowired
	private IActivityService activityService;
	@Autowired
	private IOrderFormSubInfoService orderFormSubInfoService;
	@Autowired
	private IMemberGroupService memberGroupService;

	final DecimalFormat COMMA_FORMAT = new DecimalFormat("#,###.##");

	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 活动，众筹已支付的订单总额
	 * @return
	 */
	public Double getOrderTotal(boolean isTxz, Integer type,Set<Integer> ots) {
		OrderForm orderForm = new OrderForm();
//		orderForm.setInitiatorId(RealmUtils.getCurrentUser().getId());
		orderForm.setStatus(OrderStatus.ORDER_STATUS_HAVE_PAID.getCode()); // 已支付

		orderForm.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
		Map<String, Object> params = new HashMap<String, Object>();
		List<String> initiatorIds = memberGroupService.getChildWithMy(RealmUtils.getCurrentUser().getId());
		params.put("initiatorIds", initiatorIds);

		Set<Integer> orderTypes = new HashSet<Integer>();

		if(ots==null){
			orderForm.setType(type);
		}else{
			orderTypes = ots;
		}

		if (isTxz) {
			Set<String> merchants = MerchantUtil.getTxzMerchants();
			params.put("txzMerchantId", merchants);
		}

		params.put("types", orderTypes);
		params.put("isCrowdfund", 0);
		params.put("payment", 0);
		return orderFormService.getTotalPayment(orderForm, params);
	}


	public double getTotalAccount(Integer type, String memberId, Integer withType, boolean isTxz) {
		return getTotalAccountInner(type, memberId, withType, isTxz);
	}

	public double getTotalAccount(Integer type, String memberId, Integer withType) {
		return getTotalAccountInner(type, memberId, withType, true);
	}

    /**
     * 获取余额
     * @param type 订单类型
     * @param memberId 用户
     * @param withType 提现类型
     * @return
     */
    public double getTotalAccountInner(Integer type, String memberId, Integer withType, boolean isTxz) {
        Double orderTotal = getOrderTotal(isTxz, type,null);
        Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(memberId, withType,null);

		double blance = 0.0;

		if (orderTotal == null) {
			orderTotal = 0.0;
			blance = 0;
		}
		if(withdrawalTotal == null) {
			withdrawalTotal = 0.0;
			blance = orderTotal;
		}
//
//		if (orderTotal != null) {
//			// 手续费
//			double serviceFee = BigDecimalUtils.mul(orderTotal, 0.006);
//			// 净额
//			blance = BigDecimalUtils.sub(orderTotal, serviceFee);
//			blance = BigDecimalUtils.round(blance, 2);
//		}

		if (orderTotal != null && withdrawalTotal != null) {
			blance = BigDecimalUtils.sub(orderTotal, withdrawalTotal);
		}
		return blance;
	}

	/**
	 * 用户订单列表
	 * @param page
	 * @return
	 */
	public List<OrderFormOutput> memberOrderList(Page page, OrderForm orderForm, Map<String, Object> params, String memberName) {
		if (orderForm == null) {
			orderForm = new OrderForm();
		}
		orderForm.setInitiatorId(RealmUtils.getCurrentUser().getId());
		orderForm.setStatus(OrderStatus.ORDER_STATUS_HAVE_PAID.getCode()); // 已支付

		params.put("isCrowdfund", "0");
		params.put("payment", 0);

		List<OrderForm> orderForms = this.getNewOrderList(params, null, memberName, page, orderForm);
		List<OrderFormOutput> orderFormOutputs = LangUtils.transform(orderForms, input -> {
			OrderFormOutput orderFormOutput = OrderFormOutput.transform(input);
			String label = OrderType.getValue(input.getType());
			orderFormOutput.setTypeName(label);
			// 获取商户名称
			String merchantName = orderActivityBizService.
					getMerchantName(input.getMerchantId(), input.getPaymentWay(), input.getInitiatorId(), input.getMerchantName());
			orderFormOutput.setMerchantName(merchantName);
			return orderFormOutput;
		});
		return orderFormOutputs;
	}

	/**
	 * 首页余额、套餐、机构信息
	 *
	 * @param isNeedPackage 是否需要检查套餐
	 * @return
	 */
	public Map<String, Object> memberIndexMap(boolean isNeedPackage) {
		Map<String, Object> resultMap = Maps.newHashMap();

		// 机构信息
		String memberId = RealmUtils.getCurrentUser().getId();
		MemberGroup member = memberGroupService.get(memberId);
		resultMap.put("member", member);

		String newPartnerId = memberGroupService.getPartnerId(memberId);
		MemberGroupInfo memberGroupInfo = memberGroupInfoService.findByMemberId(newPartnerId);
		if (null != memberGroupInfo) {

			resultMap.put("isEditInfo", memberGroupInfo.getIsEditInfo());
			resultMap.put("expirationTime", memberGroupInfo.getExpirationTime());

			if (null != memberGroupInfo.getExpirationTime()) {
				Long current = System.currentTimeMillis();
				Long expire = memberGroupInfo.getExpirationTime().getTime();

				Long diffTime = expire - current;

				long day = diffTime / (24 * 60 * 60 * 1000);
				long hour = (diffTime / (60 * 60 * 1000) - day * 24);
				long min = ((diffTime / (60 * 1000)) - day * 24 * 60 - hour * 60);

				boolean isExpire = MemberFormUtil.isExpire(memberId, memberGroupInfo.getExpirationTime());
				String timeStr = "";

				if (day + 1 <= 60) {
					resultMap.put("showExpire", true);
					if (day == 0) {
						if (hour > 0) {
							timeStr += hour + "小时";
						}
						if (min > 0) {
							timeStr += min + "分钟";
						}
					} else if (day > 0 && hour > 0){
						timeStr += day + 1 + "天";
					} else if (day > 0) {
						timeStr += day + "天";
					}
					resultMap.put("isExpire", isExpire);
					resultMap.put("expirationDay", timeStr);
				} else {
					resultMap.put("showExpire", false);
				}
			}
		}

		MemberPartner dbmemberPartner = memerPartnerService.findByMemberId(newPartnerId);
		Integer systemType = 0;
		if(dbmemberPartner!=null){
			systemType = dbmemberPartner.getSystemType();
		}
		resultMap.put("systemType", systemType);

		Set<Integer> orderTypes = new HashSet<>();
		orderTypes.add(OrderType.ORDER_ACTIVITY.getCode()); // 活动
		orderTypes.add(OrderType.ORDER_CROWD_FUND.getCode()); // 众筹
		orderTypes.add(OrderType.ORDER_MULTIPLE_CROWD_FUND.getCode());

		Double totalAccount =getOrderTotal(false, null,orderTypes);
		if(null==totalAccount){
			totalAccount = 0d;
		}
		resultMap.put("totalPayment", totalAccount);

		// 机构套餐角色相关
		if (isNeedPackage) {
			List<SysRole> sysRoles = Lists.newArrayList();
			PackageMember packageMember = packageBizService.getPackageMember(memberId, sysRoles);
			resultMap.put("sysRoles", sysRoles);
			if (packageMember != null) {
				ProductPackage productPackage = packageService.get(packageMember.getLevelId());
				resultMap.put("productPackage", productPackage);
			}
			resultMap.put("packageMember", packageMember);

			// 是否开启套餐购买配置
			SysConfig sysConfig = sysConfigService.findByCode("packageBuy");
			resultMap.put("sysConfig", sysConfig);

			PackageCount packageCount = packageCountService.getUnique(new PackageCount(memberId, TargetType.PUSH_SMS.getCode()));
			if (packageCount == null) {
				packageCount = new PackageCount();
				// 短信预警默认配置
				SysConfig smsWarnConfig = sysConfigService.findByCode(PackageCount.SMS_WARN_NUM_DEFAULT);
				// 短信超出使用默认配置
				SysConfig smsExcessConfig = sysConfigService.findByCode(PackageCount.SMS_EXCESS_NUM_DEFAULT);
				packageCount.setIsOpen(YesNoStatus.NO_NEW.getCode()); // 默认关闭
				if (smsWarnConfig != null) {
					packageCount.setWarnNum(Integer.valueOf(smsWarnConfig.getValue()));
				} else {
					packageCount.setWarnNum(0);
				}
				if (smsExcessConfig != null) {
					packageCount.setExcessNum(Integer.valueOf(smsExcessConfig.getValue()));
				} else {
					packageCount.setExcessNum(0);
				}
			}
			resultMap.put("packageCount", packageCount);
		}


		//是否绑定
		boolean isBand = (null != member) && (YesNoStatus.YES.getCode().equals(member.getOpenStatus())) ;
		totalAccount = getTotalAccount(null, memberId, Withdrawals.TYPE_CROWD_FUNDING, true);
		if (totalAccount > Float.valueOf(0.0f)) {
			isBand = false;
		}
		resultMap.put("isBand", isBand);
		return resultMap;
	}

	/**
	 * 获取主题的订单数据
	 *
	 * @param eventId 主题编号
	 * @return
	 */
	public Map<String, Double> getOrderData(String eventId,Integer payType) {
		// 支付总额
		Double payMoney = orderFormService.getOrderData(eventId, OrderStatus.ORDER_STATUS_HAVE_PAID.getCode(),payType);
		// 退款总额,
		Double refundMoney = orderFormService.getOrderData(eventId, OrderStatus.ORDER_STATUS_REFUND.getCode(),payType);

		// 累计总额
		Double totalMoney = BigDecimalUtils.add(payMoney, refundMoney);
		totalMoney = BigDecimalUtils.round(totalMoney, 2);

		// 剩余总额
		Double remainMoney = BigDecimalUtils.sub(totalMoney, refundMoney);
		remainMoney = BigDecimalUtils.round(remainMoney, 2);

		Map<String, Double> orderData = Maps.newHashMap();
		orderData.put("totalMoney", totalMoney);
		orderData.put("refundMoney", BigDecimalUtils.round(refundMoney, 2));
		orderData.put("remainMoney", remainMoney);
		return orderData;
	}

/*
    *//**
	 * 获取主题的订单数据
	 *
	 * @param eventId 主题编号
	 * @return
	 *//*
	public Map<String, Double> getDpOrderData(String eventId) {
		// 支付总额
		Double payMoney = orderFormService.getDpOrderData(eventId, OrderStatus.ORDER_STATUS_HAVE_PAID.getCode());
		// 退款总额
		Double refundMoney = orderFormService.getDpOrderData(eventId, OrderStatus.ORDER_STATUS_REFUND.getCode());

		// 累计总额
		Double totalMoney = BigDecimalUtils.add(payMoney, refundMoney);
		totalMoney = BigDecimalUtils.round(totalMoney, 2);

		// 剩余总额
		Double remainMoney = BigDecimalUtils.sub(totalMoney, refundMoney);
		remainMoney = BigDecimalUtils.round(remainMoney, 2);

		Map<String, Double> orderData = Maps.newHashMap();
		orderData.put("totalMoney", totalMoney);
		orderData.put("refundMoney", BigDecimalUtils.round(refundMoney, 2));
		orderData.put("remainMoney", remainMoney);
		return orderData;
	}*/

	/**
	 * @param params        查询参数
	 * @param initiatorName 所属者
	 * @param memberName    下单者
	 * @param page          分页
	 * @param orderForm     订单
	 * @return java.util.List<com.party.core.model.order.OrderForm>
	 * @Author yifeng
	 * @Description 订单管理查询
	 * @Date 13:39 2018/12/29
	 **/
	public List<OrderForm> getNewOrderList(Map<String, Object> params, String initiatorName,
										   String memberName, Page page, OrderForm orderForm) {
		// 判断输入的是否为商户号
		params.put("merchantIdBoolean", StringUtils.isNumeric(orderForm.getMerchantId()));

		// 判断输入的是否为id
		boolean initiatorBoolean = UUIDUtils.isUUID(initiatorName);
		boolean memberBoolean = UUIDUtils.isUUID(memberName);
		params.put("initiatorBoolean", initiatorBoolean);
		params.put("memberBoolean", memberBoolean);

		long start = System.currentTimeMillis();
		Integer totalCount;
		if ((StringUtils.isNotEmpty(initiatorName) && !initiatorBoolean)
				|| (StringUtils.isNotEmpty(memberName) && !memberBoolean)) {
			totalCount = orderFormService.newWebListCountNew(orderForm, params);
		} else {
			totalCount = orderFormService.newWebListCount(orderForm, params);
		}

		page.setTotalCount(totalCount);

		Map<String, Object> pageParams = CommonInput.appendPageParams(page);
		params.putAll(pageParams);

		long end = System.currentTimeMillis();
		System.out.println("count sql执行完" + (end - start) / 1000);

		start = System.currentTimeMillis();

		List<OrderForm> orderForms = Lists.newArrayList();
		if ((StringUtils.isNotEmpty(initiatorName) && !initiatorBoolean)
				|| (StringUtils.isNotEmpty(memberName) && !memberBoolean)) {
			orderForms = orderFormService.newWebListPageNew(orderForm, params);
		} else {
			orderForms = orderFormService.newWebListPage(orderForm, params);
		}

		end = System.currentTimeMillis();
		System.out.println("page sql执行完" + (end - start) / 1000);
		return orderForms;
	}
	public BookOrderInput createBookOrder(ApplyInput applyInput) {
		BookOrderInput bookOrderInput = new BookOrderInput();
		bookOrderInput.setType(applyInput.getOrderType());
		bookOrderInput.setStatus(OrderStatus.ORDER_STATUS_TO_BE_PAID.getCode());// 更改为“待支付”状态
		bookOrderInput.setPayment(applyInput.getPayment());
		bookOrderInput.setGoodsId(applyInput.getId());
		bookOrderInput.setUnit(1);
		bookOrderInput.setLinkman(applyInput.getRealname());
		bookOrderInput.setPhone(applyInput.getMobile());
		bookOrderInput.setStoreGoodsId(applyInput.getStoreGoodsId());
		return bookOrderInput;
	}

	/**
	 * 订单预定
	 *
	 * @param input    输入视图
	 * @param memberId 会员主键
	 * @return 订单信息
	 */
	@Transactional
	public OrderOutput bookActOrder(BookOrderInput input, String memberId) throws BusinessException {
		OrderForm orderForm = new OrderForm();
		orderForm.setMemberId(memberId);
		Activity activity = activityService.get(input.getGoodsId());
		if (null == activity) {
			throw new BusinessException(PartyCode.ACTIVITY_UNEXIST, "活动不存在");
		}
		if (com.party.common.utils.StringUtils.isNotEmpty(input.getMerchantId())) {
			orderForm.setMerchantId(input.getMerchantId());
		}
		orderForm.setGoodsId(input.getGoodsId());
		orderForm.setUnit(input.getUnit());
		orderForm.setLinkman(input.getLinkman());
		orderForm.setPhone(input.getPhone());
		orderForm.setType(input.getType());
		orderForm.setStatus(input.getStatus());
		orderForm.setIsPay(PaymentState.NO_PAY.getCode());
		//如果是分享商品 统计
		if (!Strings.isNullOrEmpty(input.getStoreGoodsId())) {
			orderForm.setStoreGoodsId(input.getStoreGoodsId());
		}

		if (input.getPayment() == null) {
			input.setPayment(activity.getPrice());
		}

		double payment = BigDecimalUtils.mul(input.getPayment(), input.getUnit());
		double payment2 = BigDecimalUtils.round(payment, 2);
		orderForm.setPayment((float) payment2);
		orderForm.setTitle(activity.getTitle());
		orderForm.setInitiatorId(activity.getMember());
		orderFormService.insert(orderForm);

		try {
			Member member = memberService.get(orderForm.getMemberId());
			MemberGroup initiator = memberGroupService.get(orderForm.getInitiatorId());

			OrderFormSubInfo formSubInfo = new OrderFormSubInfo();
			formSubInfo.setOrderId(orderForm.getId());
			if (null != member) {
				formSubInfo.setAuthorLogo(member.getLogo());
				formSubInfo.setAuthorName(member.getRealname());
			}
			if (null != initiator) {
				formSubInfo.setInitiatorLogo(initiator.getLogo());
				formSubInfo.setInitiatorName(initiator.getRealname());
			}
			orderFormSubInfoService.insert(formSubInfo);
		} catch (Exception e) {
			logger.error("保存订单附属信息异常", e);
		}

		//输出视图
		OrderOutput orderOutput = OrderOutput.transform(orderForm);
		orderOutput.setDescription(activity.getTitle());
		orderOutput.setLogo(activity.getPic());


		//判断是否是多场活动
		if (com.party.common.utils.StringUtils.isEmpty(activity.getEventId())) {
			orderOutput.setStartTime(activity.getStartTime());
			orderOutput.setEndTime(activity.getEndTime());
		}


		return orderOutput;
	}
}
